#pragma once

#include <sys/epoll.h>
#include <cstring>
#include "log.hpp"

using namespace Logspace;

enum EpollErr
{
    CREAR_Err,
};

class Epoll
{
public:
    Epoll()
    {
        // 创建epoll模型
        _epfd = epoll_create(1);
        if (_epfd < 0)
        {
            Log(Fatal) << "epoll_create fail";
            exit(CREAR_Err);
        }
        Log(Info) << "epoll create sucess ";
    }

    void Add_fd(int fd, uint32_t event)
    {
        // 添加文件描述符到红黑树中
        struct epoll_event epevt;
        epevt.events = event;
        epevt.data.fd = fd;

        if (epoll_ctl(_epfd, EPOLL_CTL_ADD, fd, &epevt) < 0)
        {
            Log(Warning) << "epoll add error : " << strerror(errno);
        }
        Log(Info) << "epoll add sucess , fd : " << fd ;
    }

    void Del_fd(int fd)
    {
        // 删除要进行等待的文件描述符
        if (epoll_ctl(_epfd, EPOLL_CTL_DEL, fd, nullptr) < 0)
        {
            Log(Warning) << "epoll del error : " << strerror(errno);
        }
        Log(Info) << "epoll del sucess  , fd : " << fd;
    }

    void Mod_fd(int fd, uint32_t event)
    {
        // 对文件描述符的事件进行修改
        struct epoll_event epevt;
        epevt.events = event;
        epevt.data.fd = fd;
        if (epoll_ctl(_epfd, EPOLL_CTL_MOD, fd, &epevt) < 0)
        {
            Log(Warning) << "epoll mod error : " << strerror(errno);
        }
        Log(Info) << "epoll mod sucess , fd : " << fd ;
    }

    int Wait(struct epoll_event *ep_array, int max_size, int timeout)
    {
        // 进行等待
        return epoll_wait(_epfd, ep_array, max_size, timeout);
    }

private:
    int _epfd;
};